import type { Directive, DirectiveBinding } from 'vue'
import { useAuthStore } from '@/stores/auth'

interface HTMLElementExtended extends HTMLElement {
  _?: {
    originalDisplay: string
  }
}

// 权限指令
export const permission: Directive = {
  mounted(el: HTMLElementExtended, binding: DirectiveBinding<string | string[]>) {
    checkPermission(el, binding)
  },
  updated(el: HTMLElementExtended, binding: DirectiveBinding<string | string[]>) {
    checkPermission(el, binding)
  }
}

// 角色指令
export const role: Directive = {
  mounted(el: HTMLElementExtended, binding: DirectiveBinding<string | string[]>) {
    checkRole(el, binding)
  },
  updated(el: HTMLElementExtended, binding: DirectiveBinding<string | string[]>) {
    checkRole(el, binding)
  }
}

function checkPermission(el: HTMLElementExtended, binding: DirectiveBinding<string | string[]>) {
  const authStore = useAuthStore()
  const { value } = binding
  
  if (!value) {
    return
  }
  
  let hasPermission = false
  
  if (typeof value === 'string') {
    hasPermission = authStore.hasPermission(value)
  } else if (Array.isArray(value)) {
    hasPermission = authStore.hasAnyPermission(value)
  }
  
  if (!hasPermission) {
    // 保存原始 display 值
    if (!el._) {
      el._ = {
        originalDisplay: el.style.display
      }
    }
    el.style.display = 'none'
  } else {
    // 恢复原始 display 值
    if (el._) {
      el.style.display = el._.originalDisplay
    }
  }
}

function checkRole(el: HTMLElementExtended, binding: DirectiveBinding<string | string[]>) {
  const authStore = useAuthStore()
  const { value } = binding
  
  if (!value) {
    return
  }
  
  let hasRole = false
  
  if (typeof value === 'string') {
    hasRole = authStore.hasRole(value)
  } else if (Array.isArray(value)) {
    hasRole = authStore.hasAnyRole(value)
  }
  
  if (!hasRole) {
    // 保存原始 display 值
    if (!el._) {
      el._ = {
        originalDisplay: el.style.display
      }
    }
    el.style.display = 'none'
  } else {
    // 恢复原始 display 值
    if (el._) {
      el.style.display = el._.originalDisplay
    }
  }
}
